using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Apache.Cassandra;
using Cassandraemon.Util;


namespace Cassandraemon
{

	public class CassandraQueryProvider : IQueryProvider
	{
		public CassandraContext Context { get; set; }
		
		public CassandraQueryProvider() { }
		
		public CassandraQueryProvider(CassandraContext context) 
		{
			this.Context = context;
		}
	
		public IQueryable CreateQuery (Expression expression)
		{
			Type elementType = TypeHelper.GetElementType(expression.Type);
			
			try {
			
				return (IQueryable)Activator.CreateInstance(typeof(CassandraQueryable<>).MakeGenericType(elementType), new object[] { this, expression });
				
			} catch (System.Reflection.TargetInvocationException ex) {
			
				throw ex.InnerException;
				
			}
		}
		
		
		public IQueryable<TResult> CreateQuery<TResult> (Expression expression)
		{
			return new CassandraQueryable<TResult>(this, expression);
		}
		
		
		public object Execute (Expression expression)
		{
			return Execute<object>(expression);
		}
		
		
		public TResult Execute<TResult> (Expression expression)
		{
			bool isEnumerable = (typeof(TResult).Name == "IEnumerable`1" ||
			                     typeof(TResult).Name == "IEnumerable");
			
			return (TResult)Context.Execute(expression, isEnumerable);
		}
				
	}
}
